package com.cxl.harmony.fingerguessing.slice;

import com.cxl.harmony.fingerguessing.ResourceTable;
import com.cxl.harmony.fingerguessing.utils.CommonData;
import com.cxl.harmony.fingerguessing.utils.LogUtil;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.IAbilityConnection;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.app.Context;
import ohos.bundle.ElementName;
import ohos.event.commonevent.*;
import ohos.rpc.*;

public class FingerGuessingSlice extends AbilitySlice {
    private static final String TAG = CommonData.TAG + FingerGuessingSlice.class.getSimpleName();

    private IRemoteObject remoteObject;

    private MathRemoteProxy proxy;

    private Context context;

    private MyCommonEventSubscriber subscriber;

    private boolean isLocal;

    private int myFinger;
    private int otherFinger;

    private Text msg1Text;
    private Text msg2Text;
    private Text resultMsgText;
    private Button hammer;
    private Button scissors;
    private Button paper;
    private DirectionalLayout opArea;
    private Button reStart;

    @Override
    public void onStart(Intent intent) {
        LogUtil.info(TAG, "onStart");
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_fingerguessing);
        initAndConnectDevice(intent);
        initView();
        subscribe();
    }

    private void initView() {
        msg1Text = (Text) findComponentById(ResourceTable.Id_msg1);
        msg2Text = (Text) findComponentById(ResourceTable.Id_msg2);
        resultMsgText = (Text) findComponentById(ResourceTable.Id_result_msg);
        hammer = (Button) findComponentById(ResourceTable.Id_hammer);
        scissors = (Button) findComponentById(ResourceTable.Id_scissors);
        paper = (Button) findComponentById(ResourceTable.Id_paper);
        opArea = (DirectionalLayout) findComponentById(ResourceTable.Id_op_area);
        reStart = (Button) findComponentById(ResourceTable.Id_re_start);

        hammer.setClickedListener(new ButtonClick());
        scissors.setClickedListener(new ButtonClick());
        paper.setClickedListener(new ButtonClick());
        reStart.setClickedListener(new ButtonClick());
    }

    private class ButtonClick implements Component.ClickedListener {
        @Override
        public void onClick(Component component) {
            int btnId = component.getId();
            switch (btnId) {
                case ResourceTable.Id_hammer:
                    myFinger = 3;
                    senDataToRemote();
                    break;
                case ResourceTable.Id_scissors:
                    myFinger = 2;
                    senDataToRemote();
                    break;
                case ResourceTable.Id_paper:
                    myFinger = 1;
                    senDataToRemote();
                    break;
                case ResourceTable.Id_re_start:
                    reStart();
                    break;
                default:
                    LogUtil.info(TAG, "Click default");
                    break;
            }
        }
    }

    private void reStart(){
        myFinger = 0;
        otherFinger = 0;
        senDataToRemote();
    }

    private void senDataToRemote() {
        if (remoteObject != null && proxy != null) {
            try {
                proxy.senDataToRemote(MathRemoteProxy.REQUEST_SEND_DATA);
            } catch (RemoteException e) {
                LogUtil.info(TAG, "processEvent RemoteException");
            }
        }
        checkShowMsg();
    }

    private void checkShowMsg() {
        if (myFinger > 0){
            opArea.setVisibility(Component.INVISIBLE);
        }else{
            opArea.setVisibility(Component.VISIBLE);
        }
        String msg1 = "";
        if (myFinger == 3) {
            msg1 = "锤子";
        } else if (myFinger == 2) {
            msg1 = "剪刀";
        } else if (myFinger == 1) {
            msg1 = "布";
        } else {
            msg1 = "没出";
        }
        msg1Text.setText(msg1);
        String msg2 = "";
        if (otherFinger == 3) {
            msg2 = "锤子";
        } else if (otherFinger == 2) {
            msg2 = "剪刀";
        } else if (otherFinger == 1) {
            msg2 = "布";
        } else {
            msg2 = "没出";
        }
        msg2Text.setText(msg2);
        if(myFinger == 0 || otherFinger == 0){
            resultMsgText.setText("");
        }else if(myFinger == otherFinger){
            resultMsgText.setText("平局");
        }else if(myFinger == 1 && otherFinger == 3){
            //我方布对方锤子 我方赢
            resultMsgText.setText("我方赢");
        }else if(myFinger == 3 && otherFinger == 1){
            //我方锤子对方布 对方赢
            resultMsgText.setText("对方赢");
        }else if(myFinger > otherFinger){
            resultMsgText.setText("我方赢");
        }else{
            resultMsgText.setText("对方赢");
        }
        if( isLocal && myFinger > 0 && otherFinger > 0){
            reStart.setVisibility(Component.VISIBLE);
        }else{
            reStart.setVisibility(Component.INVISIBLE);
        }
    }

    /**
     * Initialize and connect the device
     *
     * @param intent intent
     */
    private void initAndConnectDevice(Intent intent) {
        // Page initialization
        context = FingerGuessingSlice.this;
        String remoteDeviceId = intent.getStringParam(CommonData.KEY_REMOTE_DEVICEID);
        isLocal = intent.getBooleanParam(CommonData.KEY_IS_LOCAL, false);
        if (findComponentById(ResourceTable.Id_text_title) instanceof Text) {
            Text textTitle = (Text) findComponentById(ResourceTable.Id_text_title);
            textTitle.setText(isLocal ? "本地端" : "远程端");
        }

        // Connect to remote service
        if (!remoteDeviceId.isEmpty()) {
            connectRemotePa(remoteDeviceId);
        } else {
            LogUtil.info(TAG, "localDeviceId is null");
        }
    }

    private void connectRemotePa(String deviceId) {
        if (!deviceId.isEmpty()) {
            Intent connectPaIntent = new Intent();
            Operation operation = new Intent.OperationBuilder().withDeviceId(deviceId)
                    .withBundleName(getBundleName())
                    .withAbilityName(CommonData.FINGERGUESSING_SERVICE_NAME)
                    .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                    .build();
            connectPaIntent.setOperation(operation);

            IAbilityConnection conn = new IAbilityConnection() {
                @Override
                public void onAbilityConnectDone(ElementName elementName, IRemoteObject remote, int resultCode) {
                    LogUtil.info(TAG, "onAbilityConnectDone......");
                    connectAbility(elementName, remote, resultCode);
                }

                @Override
                public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
                    LogUtil.info(TAG, "onAbilityDisconnectDone......");
                    disconnectAbility(this);
                }
            };

            context.connectAbility(connectPaIntent, conn);
        }
    }

    private void connectAbility(ElementName elementName, IRemoteObject remote, int resultCode) {
        remoteObject = remote;
        proxy = new MathRemoteProxy(remote);
        LogUtil.info(TAG, "connectRemoteAbility done connected to local service");
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unSubscribe();
    }

    private void subscribe() {
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(CommonData.FINGERGUESSING_EVENT);
        matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_SCREEN_ON);
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        subscriber = new MyCommonEventSubscriber(subscribeInfo);
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
        } catch (RemoteException e) {
            LogUtil.error("", "subscribeCommonEvent occur exception.");
        }
    }

    private void unSubscribe() {
        try {
            CommonEventManager.unsubscribeCommonEvent(subscriber);
        } catch (RemoteException e) {
            LogUtil.error(TAG, "unSubscribe Exception");
        }
    }

    /**
     * Establish a remote connection
     */
    class MathRemoteProxy implements IRemoteBroker {
        private static final int ERR_OK = 0;

        private static final int REQUEST_START_ABILITY = 1;

        private static final int REQUEST_SEND_DATA = 2;

        private final IRemoteObject remote;

        MathRemoteProxy(IRemoteObject remote) {
            this.remote = remote;
        }

        @Override
        public IRemoteObject asObject() {
            return remote;
        }

        private void senDataToRemote(int requestType) throws RemoteException {
            LogUtil.info(TAG, "send data to local draw service");
            MessageParcel data = MessageParcel.obtain();
            MessageParcel reply = MessageParcel.obtain();
            MessageOption option = new MessageOption(MessageOption.TF_SYNC);
            try {
                data.writeInt(myFinger);
                remote.sendRequest(requestType, data, reply, option);
                int ec = reply.readInt();
                if (ec != ERR_OK) {
                    LogUtil.error(TAG, "RemoteException:");
                }
            } catch (RemoteException e) {
                LogUtil.error(TAG, "RemoteException:");
            } finally {
                data.reclaim();
                reply.reclaim();
            }
        }
    }

    /**
     * MyCommonEventSubscriber
     */
    class MyCommonEventSubscriber extends CommonEventSubscriber {
        MyCommonEventSubscriber(CommonEventSubscribeInfo info) {
            super(info);
        }

        @Override
        public void onReceiveEvent(CommonEventData commonEventData) {
            Intent intent = commonEventData.getIntent();
            otherFinger = intent.getIntParam(CommonData.KEY_FINGER, 0);
            LogUtil.info(TAG, "onReceiveEvent.....");
            if(otherFinger == 0){
                myFinger = 0;
            }
            checkShowMsg();
        }
    }
}
